package l1j.server.server;

import java.util.logging.Logger;

import l1j.server.server.datatables.SprTable;
import l1j.server.server.model.Instance.L1PcInstance;

public class IntervalChecker {
	private L1PcInstance _pc;
	private long _lastCheckTime_attack;
	private long _lastCheckTime_magic_dir;
	private long _lastCheckTime_magic_no_dir;
	private long _lastCheckTime_move;
	private int checkCounter_attack = 0;
	private int checkCounter_magic_dir = 0;
	private int checkCounter_magic_no_dir = 0;
	private int checkCounter_move = 0;
	private static final Logger _log = Logger.getLogger(IntervalChecker.class
			.getName());

	public IntervalChecker(L1PcInstance pc) {
		_pc = pc;
		long now = System.currentTimeMillis();
		_lastCheckTime_attack = now;
		_lastCheckTime_magic_no_dir = now;
		_lastCheckTime_magic_no_dir = now;
		_lastCheckTime_move = now;
	}

	public boolean checkAttack() {
		checkCounter_attack++;
		if ((checkCounter_attack & 0x7) == 0) { // 每8個封包檢查一次
			long now = System.currentTimeMillis();
			long interval = now - _lastCheckTime_attack;
			_lastCheckTime_attack = now;
			if (interval < getRightInterval(ACT_TYPE.ATTACK)) {
				_log.warning(_pc.getName() + " attack interval wrong!");
				return true;
			}
		}
		return false;
	}

	public boolean checkMove() {
		checkCounter_move++;
		if ((checkCounter_move & 0x7) == 0) { // 每8個封包檢查一次
			long now = System.currentTimeMillis();
			long interval = now - _lastCheckTime_move;
			_lastCheckTime_move = now;
			if (interval < getRightInterval(ACT_TYPE.MOVE)) {
				_log.warning(_pc.getName() + " move interval wrong!");
				return true;
			}
		}
		return false;
	}

	public boolean checkmagic_dir() {
		checkCounter_magic_dir++;
		if ((checkCounter_magic_dir & 0x7) == 0) { // 每8個封包檢查一次
			long now = System.currentTimeMillis();
			long interval = now - _lastCheckTime_magic_dir;
			_lastCheckTime_magic_dir = now;
			if (interval < getRightInterval(ACT_TYPE.SPELL_DIR)) {
				_log.warning(_pc.getName() + " SPELL_DIR interval wrong!");
				return true;
			}
		}
		return false;
	}

	public boolean checkmagic_no_dir() {
		checkCounter_magic_no_dir++;
		if ((checkCounter_magic_no_dir & 0x7) == 0) { // 每8個封包檢查一次
			long now = System.currentTimeMillis();
			long interval = now - _lastCheckTime_magic_no_dir;
			_lastCheckTime_magic_no_dir = now;
			if (interval < getRightInterval(ACT_TYPE.SPELL_NODIR)) {
				_log.warning(_pc.getName() + " SPELL_NODIR interval wrong!");
				return true;
			}
		}
		return false;
	}

	public static enum ACT_TYPE {
		MOVE, ATTACK, SPELL_DIR, SPELL_NODIR
	}

	private static final double HASTE_RATE = 0.75; // 速度 * 1.33

	private static final double WAFFLE_RATE = 0.87; // 速度 * 1.15

	private static final double DOUBLE_HASTE_RATE = 0.375; // 速度 * 2.66

	private int getRightInterval(ACT_TYPE type) {
		int interval;

		// 動作判斷
		switch (type) {
		case ATTACK:
			interval = SprTable.getInstance().getAttackSpeed(
					_pc.getTempCharGfx(), _pc.getCurrentWeapon() + 1);
			break;
		case MOVE:
			interval = SprTable.getInstance().getMoveSpeed(
					_pc.getTempCharGfx(), _pc.getCurrentWeapon());
			break;
		case SPELL_DIR:
			interval = SprTable.getInstance().getDirSpellSpeed(
					_pc.getTempCharGfx());
			break;
		case SPELL_NODIR:
			interval = SprTable.getInstance().getNodirSpellSpeed(
					_pc.getTempCharGfx());
			break;
		default:
			return 0;
		}

		// 一段加速
		switch (_pc.getMoveSpeed()) {
		case 1: // 加速術
			interval *= HASTE_RATE;
			break;
		case 2: // 緩速術
			interval /= HASTE_RATE;
			break;
		default:
			break;
		}

		// 二段加速
		switch (_pc.getBraveSpeed()) {
		case 1: // 勇水
			interval *= HASTE_RATE; // 攻速、移速 * 1.33倍
			break;
		case 3: // 精餅
			interval *= WAFFLE_RATE; // 攻速、移速 * 1.15倍
			break;
		case 4: // 神疾、風走、行走
			if (type.equals(ACT_TYPE.MOVE)) {
				interval *= HASTE_RATE; // 移速 * 1.33倍
			}
			break;
		case 5: // 超級加速
			interval *= DOUBLE_HASTE_RATE; // 攻速、移速 * 2.66倍
			break;
		case 6: // 血之渴望
			if (type.equals(ACT_TYPE.ATTACK)) {
				interval *= HASTE_RATE; // 攻速 * 1.33倍
			}
			break;
		default:
			break;
		}

		// 生命之樹果實
		if (_pc.isRibrave() && type.equals(ACT_TYPE.MOVE)) { // 移速 * 1.15倍
			interval *= WAFFLE_RATE;
		}
		// 三段加速
		if (_pc.isThirdSpeed()) { // 攻速、移速 * 1.15倍
			interval *= WAFFLE_RATE;
		}
		// 風之枷鎖
		if (_pc.isWindShackle() && !type.equals(ACT_TYPE.MOVE)) { // 攻速or施法速度 /
																	// 2倍
			interval /= 2;
		}
		if (_pc.getMapId() == 5143) { // 寵物競速例外
			interval *= 0.1;
		}
		return interval * 8;
	}
}
